package com.itheima.tliasmanager.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.itheima.bcript.BCryptUtil;
import com.itheima.tliasmanager.exception.PasswordNotMatchException;
import com.itheima.tliasmanager.exception.UsernameNotExistException;
import com.itheima.tliasmanager.mapper.DeptMapper;
import com.itheima.tliasmanager.mapper.EmpExprMapper;
import com.itheima.tliasmanager.mapper.EmpMapper;
import com.itheima.tliasmanager.pojo.Dto.QueryParam;
import com.itheima.tliasmanager.pojo.Vo.PageResult;
import com.itheima.tliasmanager.pojo.domain.Dept;
import com.itheima.tliasmanager.pojo.domain.Emp;
import com.itheima.tliasmanager.pojo.domain.EmpExpr;
import com.itheima.tliasmanager.pojo.domain.EmpLog;
import com.itheima.tliasmanager.service.EmpExprService;
import com.itheima.tliasmanager.service.LogService;
import com.itheima.tliasmanager.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private EmpExprService empExprService;

    @Autowired
    private EmpExprMapper empExprMapper;

    @Autowired
    private BCryptUtil bCryptUtil;

    @Override
    public PageResult<Emp> page(QueryParam queryParam) {
        /*log.info("分页查询员工列表，参数：{}", queryParam);
        PageHelper.startPage(queryParam.getPage(), queryParam.getPageSize());

        Page<Emp> page = (Page<Emp>) empMapper.selectByCondition(queryParam);

        PageResult<Emp> pageResult = new PageResult<>();
        pageResult.setTotal(page.getTotal());
        pageResult.setRows(page.getResult());
        return pageResult;*/
        //1.创建封装分页信息的Page对象
        //功能1：封装分页查询的请求参数（页码，条数）
        //功能2：封装分页查询结果（总条数，数据）
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<Emp> page = Page.of(queryParam.getPage(), queryParam.getPageSize());

        //构建条件构建器
        LambdaQueryWrapper<Emp> wrapper = new LambdaQueryWrapper<Emp>()
                .like(queryParam.getName() != null, Emp::getName, queryParam.getName())  //name  like  %?%
                .eq(queryParam.getGender() != null, Emp::getGender, queryParam.getGender())  //gender = ?
                .between(queryParam.getBegin() != null && queryParam.getEnd() != null, Emp::getEntryDate, queryParam.getBegin(), queryParam.getEnd())//entry_date between ? and ?
                .orderByDesc(Emp::getUpdateTime); // order by update_time desc

        //2.调用mybatisplus提供的分页功能方法
        page = page(page, wrapper); //调用mybatisplus提供的业务层 分页功能 方法
        //page = empMapper.selectPage(page, null);  //调用mybatisplus提供的持久层分页 方法

        //3.自行查询并封装部门名称
        List<Emp> empList = page.getRecords();
        //3.1 如果员工列表不为空，处理部门名称
        if (empList != null && empList.size() > 0) {

            //3.1 获取所有员工所属的部门id
            List<Integer> deptIdList = empList.stream().map(emp -> emp.getDeptId()).collect(Collectors.toList());

            //3.2 判断部门id列表不为空
            if (deptIdList != null && deptIdList.size() > 0) {

                //3.3 调用mapper方法，查询部门信息
                List<Dept> deptList = deptMapper.selectBatchIds(deptIdList);

                //3.4 判断部门列表不为空
                if (deptList != null && deptList.size() > 0) {

                    //3.5 遍历所有员工
                    empList.stream().forEach(emp -> {
                        //3.6 获取每一个员工，在部门列表中查找部门信息
                        List<Dept> result = deptList.stream().filter(dept -> dept.getId() == emp.getDeptId()).collect(Collectors.toList());
                        ;
                        if (result != null && result.size() > 0) {
                            emp.setDeptName(result.get(0).getName());
                        }
                    });
                }
            }
        }
        //4.封装分页结果数据
        return new PageResult<>(page.getTotal(), page.getRecords());
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchRemove(List<Integer> ids) {
        removeBatchByIds(ids);

        empExprService.remove(new LambdaQueryWrapper<EmpExpr>().in(EmpExpr::getEmpId, ids));
    }

    @Override
    public Emp selectById(Integer id) {
        Emp emp = getById(id);
        emp.setExprList(empExprService.list(new LambdaQueryWrapper<EmpExpr>().eq(EmpExpr::getEmpId, id)));
        return emp;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateEmp(Emp emp) {
        emp.setUpdateTime(LocalDateTime.now());
        updateById(emp);

        empExprService.remove(new LambdaQueryWrapper<EmpExpr>().eq(EmpExpr::getEmpId, emp.getId()));
        List<EmpExpr> exprList = emp.getExprList();
        if (exprList != null && !exprList.isEmpty()) {
            exprList.forEach(expr -> expr.setEmpId(emp.getId()));

        }
        empExprService.saveBatch(exprList);

    }

    @Override
    public Emp chaeckLogin(Emp emp) {
        log.info("S---->员工登录：{}", emp);
        Emp loginEmp = empMapper.selectByUsername(emp.getUsername());
        if (loginEmp == null) {
            throw new UsernameNotExistException("用户名不存在!");
        }
        if (!bCryptUtil.checkPassword(emp.getPassword(), loginEmp.getPassword())) {
            throw new PasswordNotMatchException("密码错误!");
        }

        return loginEmp;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveEmp(Emp emp) {

        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());

        //对密码进行加密
        emp.setPassword(bCryptUtil.hashPassword("123456"));

        empMapper.insert(emp);
        log.info("保存员工，参数：{}", emp);
        List<EmpExpr> exprList = emp.getExprList();
        if (exprList != null && !exprList.isEmpty()) {
            exprList.forEach(expr -> expr.setEmpId(emp.getId()));
            empExprService.saveBatch(exprList);
        }

    }
}
